#ifndef _TWOGRE_QUATERNION_VARIABLE_H_
#define _TWOGRE_QUATERNION_VARIABLE_H_

#include "TwOgrePrerequisites.h"
#include "TwOgreVariable.h"

#include "OgreQuaternion.h"
#include "OgreVector3.h"
#include "OgreString.h"

namespace TwOgre{
	
    class Window;
    
    class QuaternionParams
    {
    public:
        QuaternionParams(const Ogre::String& name)
            : parent_(0)
            , name_(name)
            , label_(Ogre::StringUtil::BLANK)
            , group_(Ogre::StringUtil::BLANK)
            , help_(Ogre::StringUtil::BLANK)
            , shortcut_(Ogre::StringUtil::BLANK)
            , type_(TW_TYPE_QUAT4F)
            , readOnly_(false)
            , data_(NULL)
            , setCB_(NULL)
            , getCB_(NULL)
            , value_(Ogre::Quaternion::IDENTITY)
            , arrow_(false)
            , arrowAxes_(Ogre::Vector3::ZERO)
        {}
     
        QuaternionParams& label(const Ogre::String& varLabel)
        {
            label_ = varLabel;
            return *this;
        }
        QuaternionParams& group(const Ogre::String& varGroup)
        {
            group_ = varGroup;
            return *this;
        }
        QuaternionParams& help(const Ogre::String& varHelp)
        {
            help_ = varHelp;
            return *this;
        }
        QuaternionParams& shortcut(const Ogre::String& varShortcut)
        {
            shortcut_ = varShortcut;
            return *this;
        }
        QuaternionParams& type(TwType varType)
        {
            type_ = varType;
            return *this;
        }
        QuaternionParams& readOnly(bool varReadOnly)
        {
            readOnly_ = varReadOnly;
            return *this;
        }
        QuaternionParams& callback(TwSetVarCallback setter, TwGetVarCallback getter, void* varData)
        {
            setCB_ = setter;
            getCB_ = getter;
            data_ = varData;
            return *this;
        }
        QuaternionParams& value(const Ogre::Quaternion& quaternionVal)
        {
            value_ = quaternionVal;
            return *this;
        }
        QuaternionParams& arrow(const bool show = true, const Ogre::Vector3& axes = Ogre::Vector3(0,0,-1))
        {
            arrow_ = show;
            arrowAxes_ = axes;
            return *this;
        }
    private:
		Window* parent_;
		Ogre::String name_;
        Ogre::String label_;
        Ogre::String group_;
        Ogre::String help_;
        Ogre::String shortcut_;
		TwType type_;
        bool readOnly_;
        void* data_;
        TwSetVarCallback setCB_;
        TwGetVarCallback getCB_;

        Ogre::Quaternion value_;

        bool arrow_;
        Ogre::Vector3 arrowAxes_;
        
        friend class Window;
		friend class QuaternionVariable;		
    };

	class TwOgreExport QuaternionVariable : public Variable
	{
	protected:
		QuaternionVariable(Window *parent, const Ogre::String& name, bool readOnly, const Ogre::String& label, 
			const Ogre::Quaternion& quat, const Ogre::String& groupName, const Ogre::String& help);
		QuaternionVariable(QuaternionParams& params);
		~QuaternionVariable();

	public:
		const Ogre::Quaternion& getQuaternionValue() const;
		void setQuaternionValue(const Ogre::Quaternion& quat);
    	void setArrow(bool show = true, const Ogre::Vector3& axes = Ogre::Vector3(0,0,-1));

	private:
		mutable Ogre::Quaternion mQuaternion;
		float mTweakQuaternion[4];

		friend class Window;
	};
}; // End Namespace
#endif
